import { component$ } from '@builder.io/qwik';
import { type DocumentHead, routeLoader$, Link, type DocumentMeta, type RequestHandler } from '@builder.io/qwik-city';
import { type UserInfo, type Post, type Tag } from '@prisma/client';
import _ from 'lodash';
import { toBigint2 } from '~/common/bigint';
import Markdown from '~/components/ui/Markdown';
import { checkAuth } from '~/server/authn';
import { noCache } from '~/server/cache-control';
import { db } from '~/server/db';
import logger from '~/server/logger';
import { userInfoService } from '~/server/service/user-info-service';
import { postApp } from '~/server/app/post-app';

export const onGet: RequestHandler = async (ev) => {
  noCache(ev);
};

type LoaderResult =
  | { found: false }
  | { found: true; post: Post; author: UserInfo | null; editable: boolean; tags: Tag[] };

export const useLoader = routeLoader$<LoaderResult>(async (requestEvent) => {
  const auth = await checkAuth(requestEvent);
  const idStr = requestEvent.params.id;

  if (_.isEmpty(idStr)) {
    return { found: false };
  }

  const { ok, value: id } = toBigint2(idStr);
  if (!ok) {
    logger.error(`==> ${requestEvent.pathname}: invalid id`);
    return { found: false };
  }

  const result = await postApp.findPostForReading(id);
  if (!result) {
    return { found: false };
  }

  const author = await userInfoService.findByUserId(db, result.post.userId);
  const editable = auth.ok && auth.data.userId === result.post.userId;
  return { found: true, author, editable, ...result };
});

export default component$(() => {
  const loaded = useLoader();

  if (loaded.value.found === false) {
    return <div class="text-3xl font-bold w-full text-center mt-36">文章不存在！</div>;
  } else {
    const { post, tags } = loaded.value;
    return (
      <div style={{ maxWidth: 800 }} class="mx-auto px-2">
        <h1 class="text-3xl text-kq-900 font-bold my-6">{post.title}</h1>
        <div class="text-sm text-gray-500">
          {loaded.value.author ? (
            <span>
              <a href={`/users/${loaded.value.author.userId.toString()}`}>{loaded.value.author.nickname}</a>
            </span>
          ) : null}
          <span class="ml-2">{post.createTime.toLocaleString('zh-CN')}</span>
          &emsp;
          {loaded.value.editable && <Link href={`/update/post/${post.id}`}>编辑本文</Link>}
        </div>
        <div>{post.type === 'MD' ? <Markdown value={post.content} /> : <div>{post.content}</div>}</div>
        {_.isEmpty(tags) || (
          <div class="flex gap-1 items-center">
            相关标签：{' '}
            {tags.map((it) => (
              <span class="border rounded-full px-4 py-2 bg-kq-50" key={it.id.toString()}>
                {it.name}
              </span>
            ))}
          </div>
        )}
      </div>
    );
  }
});

export const head: DocumentHead = ({ resolveValue }) => {
  const loaded = resolveValue(useLoader);

  if (loaded.found) {
    const meta: DocumentMeta[] = [];
    const tags = loaded.tags;
    if (tags.length > 0) {
      const tagNames = loaded.tags.map((it) => it.name).join(',');
      meta.push({ name: 'keywords', content: tagNames });
    }

    return {
      title: `${loaded.post.title}`,
      links: [{ rel: 'stylesheet', href: '/css/prism.css' }], // TODO: 精准控制要加载的样式文件
      meta,
    };
  } else {
    return {
      title: '文章不存在',
    };
  }
};
